{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Variable()和get_variable()的区别\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 区别之一就是Variable必须在构造的时候提供初始值，因此初始值在构造时确定。\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 区别之二就是Variable总是会创建新的变量，要实现变量共享就只能传递Python对象"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "from __future__ import print_function\n",
    "from __future__ import division\n",
    "\n",
    "import tensorflow as tf"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<tf.Variable 'x:0' shape=() dtype=int32_ref>\n",
      "<tf.Variable 'x_1:0' shape=() dtype=int32_ref>\n",
      "<tf.Variable 'Variable:0' shape=() dtype=int32_ref>\n"
     ]
    }
   ],
   "source": [
    "\n",
    "tf.reset_default_graph()\n",
    "x1 = tf.Variable(1, name=\"x\")\n",
    "x2 = tf.Variable(2, name=\"x\")\n",
    "print(x1)\n",
    "print(x2)\n",
    "\n",
    "# tf.Variable会自动生成名字\n",
    "x3 = tf.Variable(3)\n",
    "print(x3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<tf.Variable 'myscope/x:0' shape=(3,) dtype=int32_ref>\n",
      "<tf.Variable 'myscope/x:0' shape=(3,) dtype=int32_ref>\n"
     ]
    }
   ],
   "source": [
    "tf.reset_default_graph()\n",
    "with tf.variable_scope(\"myscope\") as scope:\n",
    "    x = tf.get_variable(name=\"x\", initializer=tf.constant([1, 2, 3]))\n",
    "    print(x)\n",
    "# 不加reuse=True会抛出异常，不允许创建同名的变量。\n",
    "# with tf.variable_scope(\"myscope\") as scope:\n",
    "#    x = tf.get_variable(name=\"x\", dtype=tf.int32, initializer=tf.constant([1, 2, 3]))\n",
    "    \n",
    "with tf.variable_scope(\"myscope\", reuse=True) as scope:\n",
    "    # 注意要加上dtype=tf.int32\n",
    "    x = tf.get_variable(name=\"x\", dtype=tf.int32, initializer=tf.constant([1, 2, 3]))\n",
    "    # 我们可以不提供initializer\n",
    "    # x = tf.get_variable(name=\"x\", dtype=tf.int32)\n",
    "    print(x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<tf.Variable 'myscope/x:0' shape=(3,) dtype=int32_ref>\n",
      "<tf.Variable 'myscope/y1:0' shape=() dtype=int32_ref>\n",
      "<tf.Variable 'myscope/x:0' shape=(3,) dtype=int32_ref>\n",
      "<tf.Variable 'myscope/y2:0' shape=() dtype=int32_ref>\n"
     ]
    }
   ],
   "source": [
    "tf.reset_default_graph()\n",
    "with tf.variable_scope(\"myscope\") as scope:\n",
    "    x = tf.get_variable(name=\"x\", initializer=tf.constant([1, 2, 3]))\n",
    "    y = tf.get_variable(name=\"y1\", initializer=tf.constant(1))\n",
    "    print(x)\n",
    "    print(y)\n",
    "\n",
    "with tf.variable_scope(\"myscope\") as scope:\n",
    "    # y不共享\n",
    "    y = tf.get_variable(name=\"y2\", initializer=tf.constant(2))\n",
    "    scope.reuse_variables()\n",
    "    x = tf.get_variable(name=\"x\", dtype=tf.int32)\n",
    "    print(x)\n",
    "    print(y)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 共享Dense层参数的示例"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[array([[-3.8509488, -2.121961 ]], dtype=float32), array([[-7.7018976, -4.243922 ]], dtype=float32)]\n"
     ]
    }
   ],
   "source": [
    "tf.reset_default_graph()\n",
    "\n",
    "x1 = tf.placeholder(dtype=tf.float32, shape=[None, 3], name=\"x1\")\n",
    "x2 = tf.placeholder(dtype=tf.float32, shape=[None, 3], name=\"x2\")\n",
    "with tf.variable_scope(\"myscope\") as scope:\n",
    "    l1 = tf.layers.Dense(units=2)\n",
    "    h11 = l1(x1)\n",
    "with tf.variable_scope(\"myscope\", reuse=True) as scope:\n",
    "    l2 = tf.layers.Dense(units=2)\n",
    "    h12 = l2(x2)\n",
    "with tf.Session() as sess:\n",
    "    sess.run(tf.global_variables_initializer())\n",
    "    print(sess.run([h11, h12], feed_dict={x1: [[1, 2, 3]], x2: [[2, 4, 6]]}))\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## name_scope和variable_scope的区别"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "var1:0\n",
      "my_scope/var2:0\n",
      "my_scope/Add:0\n",
      "my_scope/var1:0\n",
      "my_scope_1/var2:0\n",
      "my_scope_1/Add:0\n"
     ]
    }
   ],
   "source": [
    "tf.reset_default_graph()\n",
    "with tf.name_scope(\"my_scope\"):\n",
    "    v1 = tf.get_variable(\"var1\", [1], dtype=tf.float32)\n",
    "    v2 = tf.Variable(1, name=\"var2\", dtype=tf.float32)\n",
    "    a = tf.add(v1, v2)\n",
    "\n",
    "    print(v1.name)  # var1:0\n",
    "    print(v2.name)  # my_scope/var2:0\n",
    "    print(a.name)   # my_scope/Add:0\n",
    "\n",
    "with tf.variable_scope(\"my_scope\"):\n",
    "    v1 = tf.get_variable(\"var1\", [1], dtype=tf.float32)\n",
    "    v2 = tf.Variable(1, name=\"var2\", dtype=tf.float32)\n",
    "    a = tf.add(v1, v2)\n",
    "\n",
    "    print(v1.name)  # my_scope/var1:0\n",
    "    print(v2.name)  # my_scope_1/var2:0\n",
    "    print(a.name)   # my_scope_1/Add:0"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "my_scope/var2:0\n",
      "my_scope_1/var2:0\n"
     ]
    }
   ],
   "source": [
    "tf.reset_default_graph()\n",
    "with tf.name_scope(\"my_scope\"):\n",
    "    v2 = tf.Variable(1, name=\"var2\", dtype=tf.float32)\n",
    "    print(v2.name)\n",
    "\n",
    "with tf.name_scope(\"my_scope\"):\n",
    "    v2 = tf.Variable(1, name=\"var2\", dtype=tf.float32)\n",
    "    print(v2.name)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "py3.6-env",
   "language": "python",
   "name": "py3.6-env"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
